using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using OpenTK.OpenGL;
using OpenTK.OpenGL.Enums;
using Dogfight2008.Common;
using OpenTK.Math;
using System.IO;
using System.Globalization;

namespace Dogfight2008.CplViewer
{
  public partial class CplViewerForm : Form
  {
    public CplViewerForm()
    {
      InitializeComponent();
    }

    ColoredPolygonMesh mesh;
    double rot = 0;
    double y = -75;
    double x = 0, z = -20;

    private void glControl1_Paint(object sender, PaintEventArgs e)
    {
      GLUtil.Clear();
      GL.Translate(x, -y, z);
      GL.Rotate((float)rot / 3.0f, Vector3.UnitZ);
      if (mesh != null)
        DrawMesh(mesh);
      GLUtil.DrawXYZAxis(1000);
      glCtrl.SwapBuffers();
      Text = string.Format("x={0} y={1} z={2}", x, y, z);
    }

    private void DrawMesh(ColoredPolygonMesh mesh)
    {
      GLUtil.DrawMesh(mesh);
    }

    private void DrawSoup(ColoredTriangleSoup soup)
    {
      GLUtil.DrawSoup(soup);
    }

    private void glControl1_Resize(object sender, EventArgs e)
    {
      HandleResize();
    }

    private void HandleResize()
    {
      GLControlUtil.HandleResize(glCtrl, 10000);
    }

    private void Form1_Load(object sender, EventArgs e)
    {
      mesh = CplLoader.FromString(Resources.Tower);
      GLControlUtil.Init(glCtrl, 1000);
      GLUtil.SunLightDirection(1, 0, -1);
    }

    int mx,my;
    double basex, basez, basey, baserot;
    bool rotating = false;
    bool panning = false;
    bool zooming = false;
    MouseButtons panButton = MouseButtons.Left;
    MouseButtons rotButton = MouseButtons.Right;
    MouseButtons zoomButton = MouseButtons.Middle;

    private void glCtrl_MouseDown(object sender, MouseEventArgs e)
    {
      mx = e.X;
      my = e.Y;
      if (e.Button == rotButton)
      {
        baserot = rot;
        rotating = true;
      }
      if (e.Button == panButton)
      {
        basex = x;
        basez = z;
        panning = true;
      }
      if (e.Button == zoomButton)
      {
        basey = y;
        zooming = true;
      }
      y += e.Delta;
    }

    private void glCtrl_MouseMove(object sender, MouseEventArgs e)
    {
      int dx = e.X - mx;
      int dy = e.Y - my;
      if (rotating)
        rot = baserot + dx;
      if (panning)
      {
        x = basex + dx/5.0;
        z = basez - dy/5.0;
      }
      if (zooming)
        y = basey + dy;
      glCtrl.Invalidate();
    }

    private void UpdateRotLabel()
    {
      //label1.Text = rot.ToString();
    }

    private void glCtrl_MouseUp(object sender, MouseEventArgs e)
    {
      if (e.Button == rotButton)
        rotating = false;
      if (e.Button == panButton)
        panning = false;
      if (e.Button == zoomButton)
        zooming = false;
    }

    private void button1_Click(object sender, EventArgs e)
    {
      rot += 10;
      glCtrl.Invalidate();
      UpdateRotLabel();
    }

    private void button2_Click(object sender, EventArgs e)
    {
      rot -= 10;
      glCtrl.Invalidate();
      UpdateRotLabel();
    }

    private void button4_Click(object sender, EventArgs e)
    {
      y += 1;
      glCtrl.Invalidate();
    }

    private void button3_Click(object sender, EventArgs e)
    {
      y -= 1;
      glCtrl.Invalidate();
    }

    private void glCtrl_DragEnter(object sender, DragEventArgs e)
    {
      if (e.Data.GetDataPresent(DataFormats.FileDrop))
      {
        string[] files = e.Data.GetData(DataFormats.FileDrop) as string[];
        if(files.Length==1 && files[0].EndsWith(".cpl", true, CultureInfo.InvariantCulture))
          e.Effect = DragDropEffects.Copy;
      }
      else
        e.Effect = DragDropEffects.None;
    }

    private void glCtrl_DragDrop(object sender, DragEventArgs e)
    {
      string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
      string file = files[0];
      LoadFile(file);
    }

    private void LoadFile(string file)
    {
      try
      {
        mesh = CplLoader.FromString(File.ReadAllText(file));
      }
      catch
      {
        MessageBox.Show("There was an error loading the file.");
        mesh = null;
      }
      glCtrl.Invalidate();
    }
  }
}